#include "Headers.h"

bool connectSerialPort(HANDLE *portReturn)
{
	std::wstringstream portNameStream;
	std::wstring portName;
	HANDLE port;
	DCB portDcb;
	COMMTIMEOUTS portTimeouts;
	int comNo;
	scanf("%d", &comNo);
	if (comNo >= 10)
		portNameStream << L"\\\\.\\COM" << comNo;
	else
		portNameStream << L"COM" << comNo;
	portName = portNameStream.str();
	port = CreateFileW(portName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	SetupComm(port, 4096, 409);

	portDcb.DCBlength = sizeof(DCB);
	portDcb.BaudRate = CBR_9600;
	portDcb.ByteSize = 8;
	portDcb.Parity = NOPARITY;
	portDcb.StopBits = ONESTOPBIT;
	portDcb.StopBits = ONESTOPBIT;
	if (!SetCommState(port, &portDcb))
	{
		printf("ERROE: FAILED TO SET STATE\n");
		printf("%d\n", GetLastError());
		return false;
	}

	portTimeouts.ReadIntervalTimeout = 1000;
	portTimeouts.ReadTotalTimeoutMultiplier = 0;
	portTimeouts.ReadTotalTimeoutConstant = 0;
	portTimeouts.WriteTotalTimeoutMultiplier = 0;
	portTimeouts.WriteTotalTimeoutConstant = 0;
	if (!SetCommTimeouts(port, &portTimeouts))
	{
		printf("ERROE: FAILED TO SET TIMEOUTS\n");
		printf("%d\n", GetLastError());
		return false;
	}
	*portReturn = port;
	return true;
}

bool CommWrite(HANDLE port, char *writeBuffer, OVERLAPPED *portOverlapped)
{
	DWORD writeLenght = 0;
	BOOL status;
	memset(writeBuffer, 0x00, sizeof(char) * bufferSize);
	portOverlapped->Offset = 0;
	portOverlapped->OffsetHigh = 0;
	do
	{
		printf("COMMAND: ");
		std::cin.getline(writeBuffer, bufferSize);
	} while (!strcmp(writeBuffer, ""));
	PurgeComm(port, PURGE_TXCLEAR);
	status = WriteFile(port, writeBuffer, strlen(writeBuffer), NULL, portOverlapped);
	if (!status)
	{
		if (GetLastError() == ERROR_IO_PENDING || GetLastError() == ERROR_SUCCESS)
		{
			if (GetOverlappedResult(port, portOverlapped, &writeLenght, TRUE) == FALSE)
			{
				printf("ERROE: FAILED TO WRITE SErIAL PORT:\n");
				printf("%d\n", GetLastError());
				return false;
			}
		}
		else
		{
			printf("ERROE: FAILED TO WRITE SErIAL PORT:\n");
			printf("%d\n", GetLastError());
			return false;
		}
	}
	return true;
}

bool CommRead(HANDLE port, char *readBuffer, OVERLAPPED *portOverlapped)
{
	DWORD readLenght = 0;
	DWORD waitStatus = 0;
	BOOL status;

	memset(readBuffer, 0x00, sizeof(char) * bufferSize);
	portOverlapped->Offset = 0;
	portOverlapped->OffsetHigh = 0;
	status = ReadFile(port, readBuffer, bufferSize, NULL, portOverlapped);
	if (status)
	{
		printf("RECEIVED: %s\n", readBuffer);
	}
	else
	{

		if (GetLastError() == ERROR_IO_PENDING)
		{
			GetOverlappedResult(port, portOverlapped, &readLenght, TRUE);
			printf("RECEIVED: %s\n", readBuffer);
		}
		else
		{
			printf("ERROE: FAILED TO READ SErIAL PORT:\n");
			printf("%d\n", GetLastError());
			return false;
		}
	}
	PurgeComm(port, PURGE_RXCLEAR);
	return true;
}